import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import JobFairs from 'src/entities/job-fairs.entity';
import { In, Repository } from 'typeorm';
import {
  CreateJobFairsDto,
  FindJobFairsDto,
  SetJobFairsCompany,
  UpdateJobFairsDto,
} from './job-fairs.dto';
import { isEmpty } from 'lodash';
import { ApiException } from 'src/core/exceptions/api.exception';
import Company from 'src/entities/company.entity';
import User from 'src/entities/user.entity';
import Industry from 'src/entities/industry.entity';

@Injectable()
export class JobFairsService {
  constructor(
    @InjectRepository(JobFairs) private jobFairsRepository: Repository<JobFairs>,
    @InjectRepository(Company) private companyRepository: Repository<Company>,
    @InjectRepository(User) private userRepository: Repository<User>,
    @InjectRepository(Industry) private industryRepository: Repository<Industry>,
  ) {}

  // 分页查询
  async find(query: FindJobFairsDto) {
    const { page, size, enableStatus } = query;
    const queryBuilder = this.jobFairsRepository
      .createQueryBuilder('jobFairs')
      .leftJoinAndSelect('jobFairs.companys', 'company')
      .leftJoinAndSelect('company.jobs', 'job')
      .orderBy('jobFairs.createdAt', 'DESC')
      .select([
        'jobFairs.id',
        'jobFairs.title',
        'jobFairs.startTime',
        'jobFairs.endTime',
        'jobFairs.address',
        'jobFairs.image',
        'jobFairs.createdAt',
        'jobFairs.enableStatus',
        'company.id',
        'job.id',
      ])
      .skip(size * (page - 1))
      .take(size);

    if (enableStatus !== undefined) {
      queryBuilder.where('jobFairs.enable_status = :enableStatus', { enableStatus });
    }

    const [list, count] = await queryBuilder.getManyAndCount();
    return { list, count };
  }

  // 招聘会详细
  async detail(id: number) {
    const jobFairDetails = await this.jobFairsRepository
      .createQueryBuilder('jobFairs')
      .leftJoinAndSelect('jobFairs.companys', 'company')
      .leftJoinAndSelect('company.jobs', 'job', 'job.enable_status = 1')
      .leftJoinAndSelect('job.position', 'position')
      .where('jobFairs.id = :id', { id })
      .select([
        'jobFairs.id',
        'jobFairs.title',
        'jobFairs.startTime',
        'jobFairs.endTime',
        'jobFairs.address',
        'jobFairs.image',
        'company.userId',
        'company.id',
        'company.logo',
        'company.industryId',
        'company.fullName',
        'company.name',
        'company.scale',
        'company.nature',
        'job.id',
        'job.salary',
        'job.experience',
        'job.education',
        'position.name',
      ])
      .getOne();

    // 获取用户信息
    const userPromise = jobFairDetails.companys.map(async (item) => {
      const user = await this.userRepository.findOne({
        where: { id: item.userId },
        select: ['nickname', 'avatar'],
      });

      const industry = await this.industryRepository.findOne({
        where: { id: item.industryId },
        select: ['name'],
      });

      return { ...item, user, industryName: industry.name };
    });

    const company = await Promise.all(userPromise);
    const updatedJobFairDetails = { ...jobFairDetails, companys: company };
    return updatedJobFairDetails;
  }

  // 新增招聘会
  async create(createJobFairsDto: CreateJobFairsDto) {
    const jobFairs = this.jobFairsRepository.create(createJobFairsDto);
    await this.jobFairsRepository.save(jobFairs);
  }

  // 更新招聘会
  async update(updateJobFairsDto: UpdateJobFairsDto) {
    const jobFairs = await this.jobFairsRepository.findOne({ where: { id: updateJobFairsDto.id } });
    if (isEmpty(jobFairs)) {
      throw new ApiException(10101);
    }

    const newJobFairs = this.jobFairsRepository.merge(jobFairs, updateJobFairsDto);
    await this.jobFairsRepository.save(newJobFairs);
  }

  // 更新招聘会状态
  async updateStatus(id: number) {
    const jobFairs = await this.jobFairsRepository.findOne({ where: { id } });
    if (isEmpty(jobFairs)) {
      throw new ApiException(10101);
    }

    const status = jobFairs.enableStatus === 1 ? 0 : 1;
    this.jobFairsRepository.update(id, { enableStatus: status });
  }

  // 设置招聘会公司
  async setCompany(setJobFairsCompany: SetJobFairsCompany) {
    const { id, ids } = setJobFairsCompany;
    const jobFairs = await this.jobFairsRepository.findOne({ where: { id } });
    if (isEmpty(jobFairs)) {
      throw new ApiException(10101);
    }

    await this.companyRepository
      .createQueryBuilder()
      .update()
      .set({ jobFairs: jobFairs })
      .whereInIds(ids)
      .execute();
  }

  // 移除招聘会公司
  async removeCompany(setJobFairsCompany: SetJobFairsCompany) {
    const { ids } = setJobFairsCompany;
    await this.companyRepository
      .createQueryBuilder()
      .update()
      .set({ jobFairs: null })
      .whereInIds(ids)
      .execute();
  }
}
